﻿using WebApplication;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VisualStudio.TestTools.UnitTesting.Web;
using System.Diagnostics;
using System;
using System.IO;
using System.Reflection;
using System.Collections.Generic;

namespace UnitTest1856
{
    
    
    /// <summary>
    ///This is a test class for FileUtilsTest and is intended
    ///to contain all FileUtilsTest Unit Tests
    ///</summary>
    [TestClass()]
    public class FileUtilsTest
    {


        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //


        //Use ClassCleanup to run code after all tests in a class have run
        static List<string> _filesToClean = new List<string>();
        static List<string> _dirToClean = new List<string>();
        [ClassCleanup()]
        public static void MyClassCleanup()
        {
                foreach ( string file in _filesToClean )
                {
                    if ( !File.Exists( file ) )
                        continue;
                    try
                    {
                        FileAttributes a = File.GetAttributes( file );
                        a &= ~FileAttributes.ReadOnly; // turn off readonly bit
                        File.SetAttributes( file, a );
                        File.Delete( file );
                        Trace.WriteLine( string.Format( "Cleaned up (deleted) file {0}.", file ) );
                    }
                    catch ( Exception ex )
                    {
                        Trace.WriteLine( ex.ToString() );
                    }
                }
                foreach ( string dir in _dirToClean )
                {
                    if ( !Directory.Exists( dir ) )
                        continue;
                    try
                    {
                        Directory.Delete( dir );
                        Trace.WriteLine( string.Format( "Cleaned up (deleted) directory {0}.", dir ) );
                    }
                    catch ( Exception ex )
                    {
                        Trace.WriteLine( ex.ToString() );
                    }
                }
        }
        


        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion


        /// <summary>
        ///A test for GetFileNumber
        ///</summary>
        [TestMethod()]
        //[HostType( "ASP.NET" )]
        //[AspNetDevelopmentServerHost( "C:\\Projects\\DotNet3.x\\18xx\\Main", "/" )]
        //[UrlToTest( "http://localhost:2582/" )]
        [DeploymentItem( "1856.dll" )]
        public void GetFileNumberTest()
        {
            string fileName = "Fred's game_10.XML"; // Initialize to an appropriate value
            int expected = 10; // Initialize to an appropriate value
            int actual;
            actual = FileUtils_Accessor.GetFileNumber( fileName );
            Assert.AreEqual( expected, actual );
        }

        /// <summary>
        ///A test for GetFileNumber with bad file name
        ///</summary>
        [TestMethod()]
        [DeploymentItem( "1856.dll" )]
        public void GetFileNumberTest2()
        {
            string fileName = "Fred's game_"; // Initialize to an appropriate value
            int expected = 0; // Initialize to an appropriate value
            int actual;
            actual = FileUtils_Accessor.GetFileNumber( fileName );
            Assert.AreEqual( expected, actual );
        }


        /// <summary>
        ///A test for BuildFileName
        ///</summary>
        [TestMethod()]
        [DeploymentItem( "1856.dll" )]
        public void BuildFileNameTest()
        {
            string gameName = "Sam"; // Initialize to an appropriate value
            int num = 10; // Initialize to an appropriate value
            string fileExtension = "XML"; // Initialize to an appropriate value
            string expected = "Sam_10.XML"; // Initialize to an appropriate value
            string actual;
            actual = FileUtils_Accessor.BuildFileName( gameName, num, fileExtension );
            Assert.AreEqual( expected, actual );
        }

        /// <summary>
        ///A test for GetLastFileNumber
        ///</summary>
        [TestMethod()]
        public void GetLastFileNumberTest()
        {
            string directory = AppDomain.CurrentDomain.BaseDirectory;
            directory = Path.Combine( directory, "UnitTestFiles" );
            // create some temporary files
            Directory.CreateDirectory( directory );
            _dirToClean.Add( directory );

            string gameName = "UnitTestGame"; 
            string fileExtension = "XML";
            int num = 10;

            // create three files
            for ( int x = num; x < num + 3; x++ )
            {
                string fileName = FileUtils_Accessor.BuildFileName( gameName, x, fileExtension );
                string filePath = Path.Combine( directory, fileName );
                using ( FileStream fs = File.Create( filePath ) ) // create, save, and close
                {
                    Trace.WriteLine( string.Format( "Creating test file {0}.", filePath ) );
                }
                _filesToClean.Add( filePath );
            }

            
            
            int expected = 12; // Initialize to an appropriate value
            int actual;
            actual = FileUtils_Accessor.GetLastFileNumber( directory, gameName );
            Assert.AreEqual( expected, actual );
        }

        /// <summary>
        ///A test for GetNextFileName
        ///</summary>
        [TestMethod()]
        public void GetNextFileNameTest()
        {
            string directory = AppDomain.CurrentDomain.BaseDirectory;
            directory = Path.Combine( directory, "UnitTestFiles" );
            // create some temporary files
            Directory.CreateDirectory( directory );
            _dirToClean.Add( directory );

            string gameName = "UnitTestGame2";
            string fileExtension = "XML";
            int num = 10;

            // create three files
            for ( int x = num; x < num + 3; x++ )
            {
                string fileName = FileUtils_Accessor.BuildFileName( gameName, x, fileExtension );
                string filePath = Path.Combine( directory, fileName );
                using ( FileStream fs = File.Create( filePath ) ) // create, save, and close
                {
                    Trace.WriteLine( string.Format( "Creating test file {0}.", filePath ) );
                }
                _filesToClean.Add( filePath );
            }

            string expected = Path.Combine( directory, "UnitTestGame2_13.XML" ); 
            string actual;
            actual = FileUtils.GetNextFileName( directory, gameName, fileExtension );
            Assert.AreEqual( expected, actual );
            // verify that no errors occurred
            Assert.IsFalse( FileUtils.ErrorsOccurred );
            Assert.AreEqual( 0, FileUtils.Errors.Count );

            // verify that the files are still present - they should not have been deleted yet
            for ( int x = num; x < num + 3; x++ )
            {
                string fileName = FileUtils_Accessor.BuildFileName( gameName, x, fileExtension );
                string filePath = Path.Combine( directory, fileName );
                bool exists = File.Exists( filePath );
                Assert.IsTrue( exists );
            }
        }


        /// <summary>
        ///A test for GetNextFileName
        ///</summary>
        [TestMethod()]
        public void GetNextFileNameTest_DeleteOldFiles()
        {
            string directory = AppDomain.CurrentDomain.BaseDirectory;
            directory = Path.Combine( directory, "UnitTestFiles" );
            // create some temporary files
            Directory.CreateDirectory( directory );
            _dirToClean.Add( directory );

            string gameName = "UnitTestGame3";
            string fileExtension = "XML";
            int num = 10;

            // create five files
            for ( int x = num; x < num + 5; x++ )
            {
                string fileName = FileUtils_Accessor.BuildFileName( gameName, x, fileExtension );
                string filePath = Path.Combine( directory, fileName );
                using ( FileStream fs = File.Create( filePath ) ) // create, save, and close
                {
                    Trace.WriteLine( string.Format( "Creating test file {0}.", filePath ) );
                }
                _filesToClean.Add( filePath );
            }

            string expected = Path.Combine( directory, "UnitTestGame3_15.XML" );
            string actual;

            FileUtils.MaxFiles = 3; // should cause two oldest files to get deleted
            actual = FileUtils.GetNextFileName( directory, gameName, fileExtension );
            Assert.AreEqual( expected, actual );

            // verify that no errors occurred
            Assert.IsFalse( FileUtils.ErrorsOccurred );
            Assert.AreEqual( 0, FileUtils.Errors.Count );

            // verify that the two oldest files got deleted
            for ( int x = num; x < num + 2; x++ )
            {
                string fileName = FileUtils_Accessor.BuildFileName( gameName, x, fileExtension );
                string filePath = Path.Combine( directory, fileName );
                bool exists = File.Exists( filePath );
                Assert.IsFalse( exists, string.Format( "{0} should have been deleted", filePath ) );
            }

            // verify that the newer files are still present - they should not have been deleted yet
            for ( int x = num + 2; x < num + 5; x++ )
            {
                string fileName = FileUtils_Accessor.BuildFileName( gameName, x, fileExtension );
                string filePath = Path.Combine( directory, fileName );
                bool exists = File.Exists( filePath );
                Assert.IsTrue( exists, string.Format( "{0} should not have been deleted", filePath ) );
            }
        }

        /// <summary>
        ///A test for GetNextFileName.
        ///Causes an error in the deletion of old files
        ///</summary>
        [TestMethod()]
        public void GetNextFileNameTest_CauseErrorInDeleteOldFiles()
        {
            string directory = AppDomain.CurrentDomain.BaseDirectory;
            directory = Path.Combine( directory, "UnitTestFiles" );
            // create some temporary files
            Directory.CreateDirectory( directory );
            _dirToClean.Add( directory );

            string gameName = "UnitTestGame4";
            string fileExtension = "XML";
            int num = 10;

            // create five files
            for ( int x = num; x < num + 5; x++ )
            {
                string fileName = FileUtils_Accessor.BuildFileName( gameName, x, fileExtension );
                string filePath = Path.Combine( directory, fileName );
                using ( FileStream fs = File.Create( filePath ) ) // create, save, and close
                {
                    Trace.WriteLine( string.Format( "Creating test file {0}.", filePath ) );
                }
                // set the readonly bit
                FileAttributes a = File.GetAttributes( filePath );
                a |= FileAttributes.ReadOnly; // turn on readonly bit
                File.SetAttributes( filePath, a );
                _filesToClean.Add( filePath );
            }

            string expected = Path.Combine( directory, "UnitTestGame4_15.XML" );
            string actual;

            FileUtils.MaxFiles = 3; // should cause two oldest files to get deleted, but will not be able to
            actual = FileUtils.GetNextFileName( directory, gameName, fileExtension );
            Assert.AreEqual( expected, actual );

            // verify that errors occurred
            Assert.IsTrue( FileUtils.ErrorsOccurred );
            Assert.AreEqual( 2, FileUtils.Errors.Count );
            // print the error messages
            foreach ( Exception ex in FileUtils.Errors )
            {
                Trace.WriteLine( ex.ToString() );
            }

            // verify that the two oldest files did NOT get delete, and that errors occurred
            for ( int x = num; x < num + 2; x++ )
            {
                string fileName = FileUtils_Accessor.BuildFileName( gameName, x, fileExtension );
                string filePath = Path.Combine( directory, fileName );
                bool exists = File.Exists( filePath );
                Assert.IsTrue( exists, "should not have been deleted" );
            }

            // verify that the newer files are still present - they should not have been deleted yet
            for ( int x = num + 2; x < num + 5; x++ )
            {
                string fileName = FileUtils_Accessor.BuildFileName( gameName, x, fileExtension );
                string filePath = Path.Combine( directory, fileName );
                bool exists = File.Exists( filePath );
                Assert.IsTrue( exists, "should not have been deleted" );
            }
        }


        /// <summary>
        ///A test for IsFileInGameSet
        ///</summary>
        [TestMethod()]
        [DeploymentItem( "1856.dll" )]
        public void IsFileInGameSetTest()
        {
            bool expected = false; // TODO: Initialize to an appropriate value
            bool actual;

            string gameName = "UnitTestGame5";
            string fileExtension = "XML";
            int num = 5;

            // 1st test - should pass
            string fileName = FileUtils_Accessor.BuildFileName( gameName, num, fileExtension );
            expected = true;
            actual = FileUtils_Accessor.IsFileInGameSet( fileName, gameName );
            Assert.AreEqual( expected, actual );

            // 2nd test; game is superset of another game name
            fileName = FileUtils_Accessor.BuildFileName( "UnitTestGame50", num, fileExtension );
            expected = false;
            actual = FileUtils_Accessor.IsFileInGameSet( fileName, gameName );
            Assert.AreEqual( expected, actual );

            // 3rd test; game is subset of another game name
            fileName = FileUtils_Accessor.BuildFileName( "UnitTestGame", num, fileExtension );
            expected = false;
            actual = FileUtils_Accessor.IsFileInGameSet( fileName, gameName );
            Assert.AreEqual( expected, actual );

        }
    }
}
